27 #include <Classes.hpp>
28 #include <Controls.hpp>
29 #include <StdCtrls.hpp>
31 #include <Buttons.hpp>
32 #include <ExtCtrls.hpp>
34 #include <Dialogs.hpp>
35 #include <Graphics.hpp>
36 #include <ComCtrls.hpp>
59 #include <Filectrl.hpp>
62 #include <Vcl.HTMLHelpViewer.hpp>
63 #pragma package(smart_init)
64 #pragma link "Vcl.HTMLHelpViewer" //added at v2.0.0 for access to the .chm help file
65 #pragma resource "*.dfm"
84 Screen->Cursor = TCursor(-11);
150 "program operation may be restricted");
153 Application->HelpFile = AnsiString(
CurDir +
"\\Help.chm");
161 int DispW = (Screen->Width - 64) / 16;
162 int DispH = (Screen->Height - 192) / 16;
166 Display =
new TDisplay(
MainScreen,
PerformanceLogBox,
OutputLog1,
OutputLog2,
OutputLog3,
OutputLog4,
OutputLog5,
OutputLog6,
OutputLog7,
OutputLog8,
235 std::ifstream ConfigFile((
CurDir +
"\\Config.txt").c_str());
236 if(ConfigFile.fail())
239 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
245 "This program is free software released under the terms of the GNU General Public License Version 3, as published by the Free Software Foundation. "
246 "It may be used or redistributed in accordance with that license and is released in the hope that it will be useful, but WITHOUT ANY WARRANTY; "
247 "without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details - "
248 "you should have received a copy along with this program but if not see <http://www.gnu.org/licenses/>.");
252 AnsiString ConfigStr =
"";
260 AnsiString ConfigValue = ConfigStr.SubString(9, ConfigStr.Length() - 8);
261 if(ConfigStr.SubString(1, 8) ==
"Signals=")
263 if(ConfigValue ==
"right")
275 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
284 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
291 if(ConfigStr.SubString(1, 8) ==
"BgndCol=")
295 if(ConfigValue ==
"white")
299 else if(ConfigValue ==
"blue")
304 if(ConfigStr.SubString(1, 8) ==
"RLYLocn=")
306 if(DirectoryExists(ConfigValue))
312 else if(ConfigStr.SubString(1, 8) ==
"TTBLocn=")
314 if(DirectoryExists(ConfigValue))
316 TimetableDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
317 SaveTTDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
320 else if(ConfigStr.SubString(1, 8) ==
"SSNLocn=")
322 if(DirectoryExists(ConfigValue))
328 while(!ConfigFile.eof());
426 SpeedButton96->Glyph->LoadFromResourceName(0,
"ConcourseGlyph");
490 FontButton->Glyph->LoadFromResourceName(0,
"FontGraphic");
491 HomeButton->Glyph->LoadFromResourceName(0,
"Home");
510 SetGapsButton->Glyph->LoadFromResourceName(0,
"ConnectGaps");
522 CallOnImage->Picture->Bitmap->LoadFromResourceName(0,
"CallingOn");
523 CrashImage->Picture->Bitmap->LoadFromResourceName(0,
"CrashWarning");
524 DerailImage->Picture->Bitmap->LoadFromResourceName(0,
"DerailWarning");
525 SignalStopImage->Picture->Bitmap->LoadFromResourceName(0,
"SignalStopWarning");
526 SPADImage->Picture->Bitmap->LoadFromResourceName(0,
"SPADWarning");
527 TrainFailedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrainFailedWarning");
529 DistanceKey->Picture->Bitmap->LoadFromResourceName(0,
"DistanceKey");
530 PrefDirKey->Picture->Bitmap->LoadFromResourceName(0,
"PrefDirKey");
532 TrackLinkedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrackLinkedGraphic");
534 GapsNotSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsNotSetGraphic");
535 GapsSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsSetGraphic");
546 AnsiString NL =
'\n';
547 const AnsiString TTLabelStr1 =
"Start new train" + NL +
"Start new service from a split" + NL +
"Start new service from another service" + NL +
548 "Start new non-repeating shuttle finish service" + NL +
"Start new shuttle train at a timetabled stop" + NL +
549 "Start new shuttle service from a feeder";
551 const AnsiString TTLabelStr2 =
"Pass" + NL +
"Be joined by another train" + NL +
"Front split" + NL +
"Rear split" + NL +
"Change direction of train";
553 const AnsiString TTLabelStr3 =
"Finish && form a new service" + NL +
"Finish && join another train" + NL +
"Finish && exit railway" + NL +
554 "Finish && repeat shuttle, finally remain here" + NL +
"Finish && repeat shuttle, finally form a finishing service" + NL +
555 "Finish non-repeating shuttle feeder service" + NL +
"Finish && remain here";
557 const AnsiString TTLabelStr4 =
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
558 "HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
" " + NL +
"R";
560 const AnsiString TTLabelStr5 =
"HH:MM ';' Location" + NL +
"HH:MM ';' HH:MM ';' Location";
562 const AnsiString TTLabelStr6 =
"+ rear element ID - space - front element ID [+ optional ';S']" + NL +
"+ ref. of the train that splits" + NL +
563 "+ other service ref." + NL +
"+ shuttle service ref." + NL +
"+ rear element ID - space - front element ID ';' linked shuttle ref." + NL +
564 "+ linked shuttle service ref. ';' feeder service ref." + NL +
"+ location" + NL +
"+ joining train ref." + NL +
"+ new service ref." + NL +
565 "+ new service ref." + NL +
" " + NL +
"+ new service ref." + NL +
"+ ref. of train to join" + NL +
566 "+ list of valid exit element IDs (at least 1) separated by spaces" + NL +
"+ linked shuttle service ref.";
568 const AnsiString TTLabelStr7 =
"Arrival OR departure time (program will determine which from the context) + location." + NL +
569 "Arrival time, departure time (with no events between) + location";
571 const AnsiString TTLabelStr9 =
"Timetable entries" + NL +
"(service references etc.)";
572 const AnsiString TTLabelStr11 =
"Timetable" + NL +
"start time";
574 const AnsiString TTLabelStr12 =
"NB: WITHIN SERVICES commas must" + NL +
"not be used (have special meanings)," + NL +
575 "and semicolons may only be used to" + NL +
"separate service components.";
577 const AnsiString TTLabelStr13 =
"+ linked shuttle service ref. ';' finishing service ref." + NL +
"+ linked shuttle service ref.";
579 const AnsiString TTLabelStr15 =
"Repeat the service + ';' minutes between repeats ';' digit increment ';' number of repeats (last line of service)";
602 if((Screen->Width < 1024) || (Screen->Height < 768))
604 ShowMessage(
"Please note that this program works best with a screen resolution of at least 1024 x 768. Please change if possible");
610 WindowState = wsMaximized;
622 Screen->Cursor = TCursor(-2);
651 char *LocalNumericInformation = setlocale(LC_NUMERIC,
"");
653 if(LocalNumericInformation ==
"")
658 struct lconv *conv = &Locale;
664 catch(
const EFOpenError &e)
668 MessageDlg(e.Message +
" - program must terminate", mtError, But, 0);
669 Application->Terminate();
672 catch(
const Exception &e)
676 AnsiString Message =
"A fatal error occurred during the program setup process, the program must terminate. Message = " + e.Message;
677 MessageDlg(Message, mtError, But, 0);
679 Application->Terminate();
690 AnsiString ColourStr =
"", SignalStr =
"";
691 remove((
CurDir +
"\\Config.txt").c_str());
692 std::ofstream ConfigFile((
CurDir +
"\\Config.txt").c_str());
708 ConfigFile << AnsiString(
"Signals=") << SignalStr <<
'\n';
709 ConfigFile << AnsiString(
"BgndCol=") << ColourStr <<
'\n';
710 ConfigFile << AnsiString(
"RLYLocn=") << AnsiString(
LoadRailwayDialog->InitialDir) <<
'\n';
711 ConfigFile << AnsiString(
"TTBLocn=") << AnsiString(
TimetableDialog->InitialDir) <<
'\n';
712 ConfigFile << AnsiString(
"SSNLocn=") << AnsiString(
LoadSessionDialog->InitialDir) <<
'\n';
735 catch(
const Exception &e)
751 catch(
const Exception &e)
770 Screen->Cursor = TCursor(-2);
780 Screen->Cursor = TCursor(-2);
787 catch(
const Exception &e)
804 catch(
const Exception &e)
817 UnicodeString strVersion = L
"N/A";
819 VersionSize = GetFileVersionInfoSizeW(Application->ExeName.c_str(), &VersionHandle);
822 pBuffer =
new BYTE[VersionSize];
824 if(GetFileVersionInfoW(Application->ExeName.c_str(), VersionHandle, VersionSize, pBuffer))
826 VS_FIXEDFILEINFO *fi;
830 if(VerQueryValueW(pBuffer, L
"\\", (
void**)&fi, &buflen))
833 strVersion.sprintf(L
"%d.%d.%d", HIWORD(fi->dwFileVersionMS), LOWORD(fi->dwFileVersionMS), HIWORD(fi->dwFileVersionLS)
842 return L
" v" + strVersion;
858 catch(
const Exception &e)
877 catch(
const Exception &e)
891 if(((TSpeedButton*)Sender)->Down)
900 Screen->Cursor = TCursor(-11);
901 InfoPanel->Caption =
"SELECTING: Filling area with chosen element";
902 bool FillSelectionFlag =
false;
905 UnicodeString MessageStr =
"Click 'Yes' to fill the area with the chosen element or 'No' to abort.\n"
906 "Existing elements won't be overwritten although track can\n"
907 "have platforms and non-station named location elements added.\n\nThis message will not be shown again.";
908 int button = Application->MessageBox(MessageStr.c_str(), L
"", MB_YESNO);
911 FillSelectionFlag =
true;
916 bool TrackLinkingRequiredFlag =
true;
943 Screen->Cursor = TCursor(-2);
954 catch(
const Exception &e)
988 ShowMessage(
"Incomplete track or other error - see inverted element (may be behind this message)");
999 ShowMessage(
"Unable to set any track links");
1012 ShowMessage(
"Successful Completion");
1028 catch(
const Exception &e)
1049 catch(
const Exception &e)
1068 catch(
const Exception &e)
1087 catch(
const Exception &e)
1106 TFont *TempFont =
new TFont;
1114 TempText.
Font = DisplayFont;
1121 else if(Key ==
'\x1B')
1127 catch(
const Exception &e)
1146 catch(
const Exception &e)
1161 ShowMessage(
"Error, location name being entered without an entry in LNPendingList");
1181 Screen->Cursor = TCursor(-11);
1183 AnsiString ExistingName;
1191 UnicodeString MessageStr = UnicodeString(
"Another location named '") +
LocationNameTextBox->Text +
1192 UnicodeString(
"' already exists. If you continue its name will be erased. Do you wish to continue?");
1193 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
1197 Screen->Cursor = TCursor(-2);
1208 bool UseExistingPosition =
false;
1215 if(ExistingName !=
"")
1218 UseExistingPosition =
true;
1221 Screen->Cursor = TCursor(-2);
1235 bool UseExistingPosition =
false;
1237 UseExistingPosition =
true;
1240 Screen->Cursor = TCursor(-2);
1252 LocStr = LocStr.Trim();
1261 if((LocStr !=
"") && (LocStr[1] >=
'0') && (LocStr[1] <=
'9'))
1263 Screen->Cursor = TCursor(-2);
1264 ShowMessage(
"Location name can't begin with a number");
1272 if(LocStr.Length() > 50)
1274 Screen->Cursor = TCursor(-2);
1275 ShowMessage(
"Location name too long, 50 characters maximum");
1283 for(
int x = 1; x <= LocStr.Length(); x++)
1285 char Ch = LocStr[x];
1286 if((Ch !=
' ') && (Ch !=
'&') && (Ch !=
'(') && (Ch !=
')') && (Ch !=
':') && (Ch != 39) && (Ch !=
'.') && (Ch !=
'-') && (Ch !=
'+') &&
1287 (Ch !=
'/') && ((Ch <
'0') || (Ch >
'9')) && ((Ch <
'A') || (Ch >
'Z')) && ((Ch <
'a') || (Ch >
'z')))
1289 Screen->Cursor = TCursor(-2);
1291 "Location name contains one or more invalid characters, must be alphanumeric, brackets, space, full stop, colon, inverted comma, '-', '+', '/' or '&&'");
1302 Screen->Cursor = TCursor(-2);
1303 ShowMessage(
"Location name cannot be 'cdt', this name would interfere with the timetable");
1314 bool UseExistingPosition =
false;
1315 if(ExistingName !=
"")
1318 UseExistingPosition =
true;
1321 Screen->Cursor = TCursor(-2);
1330 Screen->Cursor = TCursor(-2);
1333 catch(
const Exception &e)
1354 catch(
const Exception &e)
1367 int Dist = 0, SpeedLimit = 0;
1370 DistanceStr =
"No change";
1373 SpeedStr =
"No change";
1376 if(DistanceStr ==
"No change")
1378 if(SpeedStr ==
"No change")
1388 if(((Dist != -1) && (DistanceStr.Length() > 6)) || ((SpeedLimit != -1) && (SpeedStr.Length() > 6)))
1390 ShowMessage(
"One or more entries too long");
1394 if((DistanceStr ==
"") || (SpeedStr ==
""))
1396 ShowMessage(
"One or more entries blank");
1402 for(
int x = 1; x <= DistanceStr.Length(); x++)
1404 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1406 ShowMessage(
"Track length value must be a positive whole number, or blank for no change");
1414 for(
int x = 1; x <= DistanceStr.Length(); x++)
1416 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1418 ShowMessage(
"Distance must be a positive whole number");
1426 for(
int x = 1; x <= SpeedStr.Length(); x++)
1428 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1430 ShowMessage(
"Speed limit must be a positive whole number, or blank for no change");
1438 for(
int x = 1; x <= SpeedStr.Length(); x++)
1440 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1442 ShowMessage(
"Speed limit must be a positive whole number, or 'Mixed'");
1449 Dist = DistanceStr.ToInt();
1450 if(SpeedLimit != -1)
1451 SpeedLimit = SpeedStr.ToInt();
1459 if(((Dist != -1) && (Dist < 20)) || ((SpeedLimit != -1) && (SpeedLimit < 10)) || ((SpeedLimit != -1) && (SpeedLimit >
TTrain::MaximumSpeedLimit)))
1462 ShowMessage(
"Lengths must be 20m or more, and speeds must be between 10km/h and 400km/h");
1475 bool NamedLocPresent =
false;
1478 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1480 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1483 NamedLocPresent =
true;
1487 if(NamedLocPresent && (Dist < 50))
1489 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
1492 if(NamedLocPresent && (Dist > 200))
1494 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
1497 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1499 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1536 catch(
const Exception &e)
1559 catch(
const Exception &e)
1571 TMsgDlgButtons Buttons;
1572 Buttons << mbYes << mbNo;
1573 if(MessageDlg(
"This will reset the selected elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1591 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1593 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1647 throw Exception(
"Error, XLinkPos > 1 in SetOneDefaultTrackLength at " + AnsiString(TrackElement.
HLoc) +
" & " +
1648 AnsiString(TrackElement.
VLoc));
1664 catch(
const Exception &e)
1676 TMsgDlgButtons Buttons;
1677 Buttons << mbYes << mbNo;
1678 if(MessageDlg(
"This will reset ALL track elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1699 catch(
const Exception &e)
1727 bool GraphicFoundInVector =
false;
1728 for(TTrack::TUserGraphicVector::iterator UGVIt =
Track->
UserGraphicVector.begin(); UGVIt < Track->UserGraphicVector.end(); UGVIt++)
1730 if(UGMIt->first == UGVIt->FileName)
1732 GraphicFoundInVector =
true;
1736 if(!GraphicFoundInVector)
1738 delete UGMIt->second;
1754 catch(
const Exception &e)
1794 catch(
const Exception &e)
1833 catch(
const Exception &e)
1857 catch(
const Exception &e)
1883 catch(
const Exception &e)
1902 catch(
const Exception &e)
1917 ShowMessage(
"No preferred direction selection");
1921 Screen->Cursor = TCursor(-11);
1926 Screen->Cursor = TCursor(-2);
1929 catch(
const Exception &e)
1942 TMsgDlgButtons Buttons;
1943 Buttons << mbYes << mbNo;
1944 if(MessageDlg(
"Do you really want to clear all preferred directions?", mtWarning, Buttons, 0) == mrNo)
1960 catch(
const Exception &e)
1975 Screen->Cursor = TCursor(-11);
1984 Screen->Cursor = TCursor(-2);
1987 catch(
const Exception &e)
2005 catch(
const Exception &e)
2026 catch(
const Exception &e)
2051 catch(
const Exception &e)
2076 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2078 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2086 catch(
const Exception &e)
2112 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
2114 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
2122 catch(
const Exception &e)
2148 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
2150 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
2158 catch(
const Exception &e)
2190 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2192 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2200 catch(
const Exception &e)
2215 InfoPanel->Caption =
"ROUTE CANCELLING: Right click on truncate element, first element to cancel (anywhere else to skip)";
2222 catch(
const Exception &e)
2249 catch(
const Exception &e)
2264 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
2267 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
2305 catch(
const Exception &e)
2347 catch(
const Exception &e)
2359 Screen->Cursor = TCursor(-11);
2360 std::ifstream VecFile(LoadFileName.c_str());
2361 if(!(VecFile.fail()))
2366 bool GraphicsFollow =
false;
2385 TFont *TempFont =
new TFont;
2386 TempFont->Style.Clear();
2387 TempFont->Name =
"MS Sans Serif";
2388 TempFont->Size = 10;
2390 TempFont->Charset = (TFontCharset)(0);
2399 if((LeftExcess > 0) && (RightExcess > 0))
2401 else if((LeftExcess > 0) && (RightExcess <= 0))
2404 else if((LeftExcess <= 0) && (RightExcess > 0))
2412 if((TopExcess > 0) && (BotExcess > 0))
2414 else if((TopExcess > 0) && (BotExcess <= 0))
2417 else if((TopExcess <= 0) && (BotExcess > 0))
2430 if((LastChar ==
'y') || (LastChar ==
'Y'))
2434 ShowMessage(
"Railway not ready for operation so unable to load as a .rly file. Loading as a new railway under development");
2441 Screen->Cursor = TCursor(-2);
2474 ShowMessage(
"File open failed prior to load");
2475 Screen->Cursor = TCursor(-2);
2478 ShowMessage(
"File integrity check failed - unable to load");
2493 Screen->Cursor = TCursor(-11);
2495 if(!(VecFile.fail()))
2522 ShowMessage(
"File open failed prior to save");
2523 Screen->Cursor = TCursor(-2);
2528 catch(
const Exception &e)
2544 catch(
const Exception &e)
2560 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2564 Screen->Cursor = TCursor(-11);
2567 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2571 AnsiString ShortName =
"";
2572 for(
int x = ImageFileName.Length(); x > 0; x--)
2574 if(ImageFileName[x] ==
'\\')
2576 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2580 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2581 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2582 RailwayImage->PixelFormat = pf8bit;
2588 RailwayImage->Width = HPosMax - HPosMin;
2589 RailwayImage->Height = VPosMax - VPosMin;
2597 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2598 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2599 if(NewWidth > RailwayImage->Width)
2601 RailwayImage->Width = NewWidth;
2603 if(NewHeight > RailwayImage->Height)
2605 RailwayImage->Height = NewHeight;
2610 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2611 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2612 RailwayImage->Canvas->FillRect(Rect);
2620 RailwayImage->SaveToFile(ImageFileName);
2621 delete RailwayImage;
2624 Screen->Cursor = TCursor(-2);
2627 catch(
const Exception &e)
2629 if(e.Message.Pos(
"torage") > 0)
2631 Screen->Cursor = TCursor(-2);
2632 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2633 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2652 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2656 Screen->Cursor = TCursor(-11);
2659 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2663 AnsiString ShortName =
"";
2664 for(
int x = ImageFileName.Length(); x > 0; x--)
2666 if(ImageFileName[x] ==
'\\')
2668 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2672 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2673 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2674 RailwayImage->PixelFormat = pf8bit;
2679 RailwayImage->Width = HPosMax - HPosMin;
2680 RailwayImage->Height = VPosMax - VPosMin;
2688 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2689 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2690 if(NewWidth > RailwayImage->Width)
2692 RailwayImage->Width = NewWidth;
2694 if(NewHeight > RailwayImage->Height)
2696 RailwayImage->Height = NewHeight;
2701 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2702 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2703 RailwayImage->Canvas->FillRect(Rect);
2706 for(
int x = 0; x < ((RailwayImage->Width) / 16); x++)
2708 for(
int y = 0; y < ((RailwayImage->Height) / 16); y++)
2718 RailwayImage->SaveToFile(ImageFileName);
2719 delete RailwayImage;
2722 Screen->Cursor = TCursor(-2);
2725 catch(
const Exception &e)
2727 if(e.Message.Pos(
"torage") > 0)
2729 Screen->Cursor = TCursor(-2);
2730 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2731 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2749 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2753 Screen->Cursor = TCursor(-11);
2756 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2760 AnsiString ShortName =
"";
2761 for(
int x = ImageFileName.Length(); x > 0; x--)
2763 if(ImageFileName[x] ==
'\\')
2765 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2769 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2770 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2771 RailwayImage->PixelFormat = pf8bit;
2776 RailwayImage->Width = HPosMax - HPosMin;
2777 RailwayImage->Height = VPosMax - VPosMin;
2785 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2786 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2787 if(NewWidth > RailwayImage->Width)
2789 RailwayImage->Width = NewWidth;
2791 if(NewHeight > RailwayImage->Height)
2793 RailwayImage->Height = NewHeight;
2798 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2799 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2800 RailwayImage->Canvas->FillRect(Rect);
2808 RailwayImage->SaveToFile(ImageFileName);
2809 delete RailwayImage;
2812 Screen->Cursor = TCursor(-2);
2815 catch(
const Exception &e)
2817 if(e.Message.Pos(
"torage") > 0)
2819 Screen->Cursor = TCursor(-2);
2820 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2821 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2839 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2843 Screen->Cursor = TCursor(-11);
2848 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
2849 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2854 AnsiString ShortName =
"";
2855 for(
int x = ImageFileName.Length(); x > 0; x--)
2857 if(ImageFileName[x] ==
'\\')
2859 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2863 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2864 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2865 RailwayImage->PixelFormat = pf8bit;
2870 RailwayImage->Width = HPosMax - HPosMin;
2871 RailwayImage->Height = VPosMax - VPosMin;
2879 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2880 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2881 if(NewWidth > RailwayImage->Width)
2883 RailwayImage->Width = NewWidth;
2885 if(NewHeight > RailwayImage->Height)
2887 RailwayImage->Height = NewHeight;
2892 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2893 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2894 RailwayImage->Canvas->FillRect(Rect);
2909 bool BreakFlag =
false;
2935 RailwayImage->SaveToFile(ImageFileName);
2936 delete RailwayImage;
2939 Screen->Cursor = TCursor(-2);
2942 catch(
const Exception &e)
2944 if(e.Message.Pos(
"torage") > 0)
2946 Screen->Cursor = TCursor(-2);
2947 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2948 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2976 Screen->Cursor = TCursor(-11);
2978 if(!(VecFile.fail()))
3005 ShowMessage(
"Railway failed to save - can't open file");
3006 Screen->Cursor = TCursor(-2);
3010 catch(
const Exception &e)
3024 catch(
const Exception &e)
3044 catch(
const Exception &e)
3059 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
3067 Screen->Cursor = TCursor(-2);
3070 catch(
const Exception &e)
3130 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3147 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3148 ActiveTrackElementNameMapEntry.second = 0;
3198 catch(
const Exception &e)
3247 if(TTBLFile.is_open())
3251 while(!TTBLFile.eof())
3254 if((c < 32) && (c != 13) && (c != 10) && (c !=
'\0'))
3256 ShowMessage(
"Timetable file is empty or contains non-ascii characters, codes must be between 20 and 127, or CR or LF");
3266 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3273 if(TTBLFile.is_open())
3282 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3295 char *TimetableEntryString =
new char[10000];
3298 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
3299 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
3304 AnsiString OneLine(TimetableEntryString);
3308 delete TimetableEntryString;
3313 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3349 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3350 ActiveTrackElementNameMapEntry.second = 0;
3375 catch(
const Exception &e)
3394 InfoPanel->Caption =
"Timetable mode: editor hidden";
3401 ShowHideTTButton->Hint =
"Hide the timetable editor to see the railway Shift H";
3406 catch(
const Exception &e)
3445 catch(
const Exception &e)
3484 catch(
const Exception &e)
3504 catch(
const Exception &e)
3517 bool ValidFlag =
true;
3536 TDateTime DummyTime;
3554 ShowMessage(
"One or more times excessive, not permitted to exceed 95 hours");
3558 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3560 MinsStr =
"0" + MinsStr;
3562 HrsStr =
"0" + HrsStr;
3565 NewString += HrsStr +
':' + MinsStr;
3582 catch(
const Exception &e)
3595 bool ValidFlag =
true;
3614 TDateTime DummyTime;
3632 ShowMessage(
"One or more times are now before 00:00, this is not permitted");
3636 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3638 MinsStr =
"0" + MinsStr;
3640 HrsStr =
"0" + HrsStr;
3643 NewString += HrsStr +
':' + MinsStr;
3659 catch(
const Exception &e)
3697 catch(
const Exception &e)
3743 if(OldVectorPos == 0)
3771 catch(
const Exception &e)
3830 catch(
const Exception &e)
3848 UnicodeString MessageStr =
"Are you sure this entry should be deleted?";
3849 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
3881 if(OldVectorPos == 0)
3909 catch(
const Exception &e)
3930 AnsiString TempStr =
"";
3931 bool ActiveLine =
false;
3956 while(TempStr[TempStr.Length()] ==
',')
3958 TempStr = TempStr.SubString(1, TempStr.Length() - 1);
3987 (*TTCurrentEntryPtr) = TempStr;
4057 catch(
const Exception &e)
4072 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4076 std::ofstream TTBLFile;
4111 if(TTBLFile.is_open())
4115 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4122 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4128 catch(
const Exception &e)
4143 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4147 std::ofstream TTBLFile;
4156 for(
int x =
SaveTTDialog->FileName.Length(); x > 0; x--)
4174 if(TTBLFile.is_open())
4178 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4185 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4191 catch(
const Exception &e)
4205 bool EndOfFile =
false;
4206 bool FinalCallFalse =
false;
4207 bool GiveMessagesTrue =
true;
4208 bool CheckLocationsExistInRailway =
false;
4210 CheckLocationsExistInRailway =
true;
4216 "The basic syntax seems OK but this check is very limited. Other aspects can only be checked by validating the whole timetable with the appropriate railway (.rly) loaded");
4222 catch(
const Exception &e)
4250 bool CheckLocationsExistInRailwayTrue =
true;
4253 Screen->Cursor = TCursor(-11);
4255 if(TTBLFile.is_open())
4259 ShowMessage(
"Timetable integrity OK");
4266 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4268 Screen->Cursor = TCursor(-2);
4278 catch(
const Exception &e)
4302 AnsiString TempStr = *
TEVPtr;
4340 catch(
const Exception &e)
4364 AnsiString TempStr = *
TEVPtr;
4402 catch(
const Exception &e)
4439 catch(
const Exception &e)
4454 UnicodeString MessageStr =
"All changes to the timetable will be lost - proceed?";
4455 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4466 if(TTBLFile.is_open())
4483 char *TimetableEntryString =
new char[10000];
4486 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
4487 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
4492 AnsiString OneLine(TimetableEntryString);
4496 delete TimetableEntryString;
4501 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4522 catch(
const Exception &e)
4537 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
4556 Screen->Cursor = TCursor(-2);
4561 catch(
const Exception &e)
4594 catch(
const Exception &e)
4609 UnicodeString MessageStr =
"The timetable has changed.\n\nAre you sure you want to exit without saving it?";
4610 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4626 catch(
const Exception &e)
4654 catch(
const Exception &e)
4679 catch(
const Exception &e)
4697 catch(
const Exception &e)
4720 catch(
const Exception &e)
4729 TShiftState Shift,
int X,
int Y)
4773 catch(
const Exception &e)
4786 TrainController->
LogEvent(
"OAListBoxMouseUp," + AnsiString(X) +
"," + AnsiString(Y) +
"," + AnsiString(Button));
4798 int HPos, VPos, TrainID = -1, TrackVectorPosition = -1;
4805 if(Button == mbLeft)
4820 TPoint MainScreenPoint(ScreenPosH + 8, ScreenPosV + 8);
4821 TPoint CursPos =
MainScreen->ClientToScreen(MainScreenPoint);
4822 Mouse->CursorPos = CursPos;
4830 catch(
const Exception &e)
4839 TShiftState Shift,
int X,
int Y)
4845 if(Button == mbRight)
4851 catch(
const Exception &e)
4867 if((TopPos + (Y / 13)) >=
OAListBox->Items->Count)
4875 std::advance(OACurrentEntryPtr, ((Y / 13) + TopPos));
4877 int TrainIDorTVPos = OACurrentEntryPtr->second.second;
4878 if(TrainIDorTVPos >= 0)
4884 TrainID = TrainIDorTVPos;
4895 TrackVectorPosition = -(TrainIDorTVPos + 1);
4907 PreStartTime, ActiveSegment, PostEnd} Segment;
4920 Segment = PreStartTime;
4923 if(Segment == PreStartTime)
4930 Segment = ActiveSegment;
4941 AnsiString CurrentStr = *
TEVPtr;
4942 if(CurrentStr !=
"")
4944 CurrentStr = CurrentStr.SubString(1, 10);
4945 for(
int x = 1; x < CurrentStr.Length(); x++)
4947 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
4949 CurrentStr = CurrentStr.SubString(1, (x - 1));
4958 if(Segment == ActiveSegment)
4973 AnsiString Entry = *
TEVPtr;
4978 int SCPos = Entry.Pos(
';');
4979 int CPos = Entry.Pos(
',');
4986 if((CPos == 0) && (SCPos == 0))
4988 Entry = Entry.SubString(1, 12);
4990 else if((CPos > 0) && (SCPos > 0) && (CPos < SCPos))
4992 Entry = Entry.SubString(1, CPos - 1);
4994 else if((CPos > 0) && (SCPos > 0) && (CPos > SCPos))
4996 Entry = Entry.SubString(1, SCPos - 1);
4998 else if((CPos > 0) && (SCPos == 0))
5000 Entry = Entry.SubString(1, CPos - 1);
5004 Entry = Entry.SubString(1, SCPos - 1);
5017 if(Segment == PostEnd)
5025 AnsiString CurrentStr = *
TEVPtr;
5026 if(CurrentStr !=
"")
5028 CurrentStr = CurrentStr.SubString(1, 10);
5029 for(
int x = 1; x < CurrentStr.Length(); x++)
5031 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5033 CurrentStr = CurrentStr.SubString(1, (x - 1));
5064 UnicodeString MessageStr =
5065 "If you wish to preserve the original order don't make any changes whilst in alphabetical order.\n\nIn that case use alphabetical order to find the service required, click it to display it, then revert to the original order where the same service will be displayed and can be changed.";
5066 Application->MessageBox(MessageStr.c_str(), L
"Please Note:", MB_OK | MB_ICONWARNING);
5079 std::sort(SortStart, SortEnd);
5081 bool CurrentEntryChanged =
false;
5087 CurrentEntryChanged =
true;
5090 if(!CurrentEntryChanged)
5095 AZOrderButton->Hint = AnsiString(
"Arrange services in original order Toggle with Shift+ Z");
5101 UnicodeString MessageStr =
5102 "Reverting to the original order will discard any changes made whilst in alphabetical order.\n\nTo preserve the changes click 'No', then save the timetable or use 'save as' if you wish to keep the original timetable.\n\nDo you wish to proceed?";
5103 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
5117 bool CurrentEntryChanged =
false;
5123 CurrentEntryChanged =
true;
5126 if(!CurrentEntryChanged)
5131 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
5140 catch(
const Exception &e)
5151 AnsiString OutStr =
"";
5154 while(x < ConvStr.Length())
5156 if((ConvStr[x] ==
'\r') && (ConvStr[x + 1] ==
'\n'))
5164 OutStr += ConvStr[x];
5168 if(x == ConvStr.Length())
5169 OutStr += ConvStr[x];
5174 while(OutStr[OutStr.Length()] ==
',')
5176 OutStr = OutStr.SubString(1, OutStr.Length() - 1);
5246 InfoPanel->Caption =
"Select option or change entry";
5260 bool ValidFlag =
true;
5261 for(
int x = 1; x <= AnsiAddSubText.Length(); x++)
5263 if((AnsiAddSubText[x] >
'9') || (AnsiAddSubText[x] <
'0'))
5271 if(AnsiAddSubText.ToInt() != 0)
5343 bool ServiceEntry =
true;
5348 bool ServiceEntry =
false;
5360 InfoPanel->Caption =
"Add or change entry then save it, or cancel";
5370 AnsiString((
short)ServiceEntry));
5377 int CommaPos = Data.Pos(
',');
5378 if((CommaPos == 0) && (Data !=
""))
5380 CommaPos = Data.Length() + 1;
5383 if(Data.Length() <= CommaPos)
5385 Data = Data.SubString(CommaPos + 1, Data.Length() - CommaPos);
5422 if(CurrentStr !=
"")
5424 for(
int x = 1; x < CurrentStr.Length(); x++)
5426 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5428 CurrentStr = CurrentStr.SubString(1, (x - 1));
5453 TDateTime DummyTime;
5454 bool TimesPresent =
false;
5462 TimesPresent =
true;
5469 return TimesPresent;
5483 UnicodeString MessageStr =
5484 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
5485 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5494 UnicodeString MessageStr =
"The railway has changed, exit without saving?";
5495 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5507 Application->Terminate();
5509 catch(
const Exception &e)
5532 catch(
const Exception &e)
5555 catch(
const Exception &e)
5578 catch(
const Exception &e)
5637 catch(
const Exception &e)
5655 catch(
const Exception &e)
5674 catch(
const Exception &e)
5709 catch(
const Exception &e)
5720 TrainController->
LogEvent(
"MainScreenMouseDown2," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
5722 "," + AnsiString(Y));
5733 int NoOffsetX, NoOffsetY;
5735 if(Button == mbRight)
5739 AnsiString Text =
"";
5746 Screen->Cursor = TCursor(-22);
5797 bool TrackEraseSuccessfulFlag;
5798 int ErasedTrackVectorPosition;
5799 Screen->Cursor = TCursor(-11);
5801 if(TrackEraseSuccessfulFlag)
5803 if(ErasedTrackVectorPosition > -1)
5834 Screen->Cursor = TCursor(-2);
5842 bool LeadingPointsAtLastElement =
false;
5857 if(!LeadingPointsAtLastElement)
5862 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
5877 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, continue or truncate";
5954 if((TrainID01 > -1) && (TrainID23 > -1))
6004 AnsiString LocName =
"";
6009 if((LocName ==
"") && (Train.
MidElement > -1))
6125 Screen->Cursor = TCursor(-11);
6136 Screen->Cursor = TCursor(-2);
6203 Screen->Cursor = TCursor(-11);
6205 bool TrackLinkingRequiredFlag;
6207 TSpeedButton *TempSpeedButton = 0;
6215 bool InternalChecks =
true;
6221 if(TrackLinkingRequiredFlag)
6250 Screen->Cursor = TCursor(-2);
6264 NewGI.
Width = UGMIt->second->Width;
6265 NewGI.
Height = UGMIt->second->Height;
6290 AnsiString NameString;
6300 unsigned int ValidPosition;
6311 ValidElement = InactiveTrackElement1;
6312 ValidPosition = InactivePair.first;
6317 ValidElement = InactiveTrackElement2;
6318 ValidPosition = InactivePair.second;
6329 InfoPanel->Caption =
"NAMING LOCATIONS: Enter name, 'Carriage Return' to accept, 'Escape' to quit";
6360 bool FinishElement =
false, LeadingPointsAtLastElement =
false;
6361 Screen->Cursor = TCursor(-11);
6375 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values (overall length), or right click to cancel/truncate";
6385 Screen->Cursor = TCursor(-2);
6391 if(!LeadingPointsAtLastElement)
6396 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
6413 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, need to continue or truncate";
6428 Screen->Cursor = TCursor(-2);
6433 Screen->Cursor = TCursor(-2);
6450 InfoPanel->Caption =
"CONNECTING GAPS: Connecting element selected";
6462 ShowMessage(
"All gaps set");
6490 int TrueX = 0, TrueY = 0;
6491 AnsiString ExistingText =
"";
6493 TFont *ExistingTextFont =
new TFont;
6494 int ExistingTextHPos = 0, ExistingTextVPos = 0;
6500 if((TrueX >= TextPtr->HPos) && (TrueX < (TextPtr->HPos + abs(TextPtr->Font->Height))) && (TrueY >= TextPtr->VPos) && (TrueY <
6501 (TextPtr->VPos + abs(TextPtr->Font->Height))))
6503 ExistingText = TextPtr->TextString;
6504 ExistingTextFont->Assign(TextPtr->Font);
6505 ExistingTextHPos = TextPtr->HPos;
6506 ExistingTextVPos = TextPtr->VPos;
6518 TextBox->Font->Assign(ExistingTextFont);
6520 Text_X = ExistingTextHPos;
6521 Text_Y = ExistingTextVPos;
6536 TextBox->Text =
"New Text: CR=end, ESC=quit";
6539 delete ExistingTextFont;
6631 Screen->Cursor = TCursor(-11);
6640 ShowMessage(
"Preferred direction added");
6644 Screen->Cursor = TCursor(-2);
6663 Screen->Cursor = TCursor(-2);
6667 Screen->Cursor = TCursor(-2);
6764 AnsiString(PDE.
VLoc));
6777 bool PointsChanged =
false;
6778 IDInt ReqPosRouteID(-1);
6780 bool CallonTrue =
true;
6829 float TempSpeedVal = 1;
6897 int DivergingPosition = TrackElement.
Conn[3];
6899 DivergingPosition)))
6927 bool TrainPresent =
false;
6931 int BDVectorPos = -1;
6939 TDateTime TempExcessLCDownTime;
6948 if(TempExcessLCDownTime > TDateTime(0))
6977 AnsiString Message = AnsiString(
"This will open the level crossing manually (it will show in green).\n\nA manually opened"
6978 " level crossing must be manually closed, and as soon as possible to avoid time penalties.\n\n"
6979 "This message will not be shown again.");
7018 InfoPanel->Caption =
"PRE-START: Select next route location";
7020 InfoPanel->Caption =
"OPERATING: Select next route location";
7032 bool CallonFalse =
false;
7039 InfoPanel->Caption =
"PRE-START: Select next route location";
7041 InfoPanel->Caption =
"OPERATING: Select next route location";
7059 Screen->Cursor = TCursor(-11);
7061 bool PointsChanged =
false;
7071 float TempSpeedVal = 1;
7076 else if(PointsChanged)
7087 Screen->Cursor = TCursor(-2);
7095 bool CallonFalse =
false;
7101 float TempSpeedVal = 1;
7106 else if(PointsChanged)
7120 Screen->Cursor = TCursor(-2);
7129 catch(
const Exception &e)
7143 TrainController->
LogEvent(
"MainScreenMouseDown3," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7145 "," + AnsiString(Y));
7146 if(Button != mbLeft)
7152 Screen->Cursor = TCursor(-22);
7158 int HRounding, VRounding;
7209 else if(TempLevel2OperMode ==
Operating)
7212 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
7216 else if(TempLevel2OperMode ==
Paused)
7219 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7225 else if(TempLevel2OperMode ==
PreStart)
7228 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7239 catch(
const Exception &e)
7329 if(CurrentHLoc >= StartHLoc)
7333 if(CurrentVLoc >= StartVLoc)
7345 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7359 if(CurrentHLoc >= StartHLoc)
7363 if(CurrentVLoc >= StartVLoc)
7375 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7434 catch(
const Exception &e)
7470 TrainController->
LogEvent(
"MainScreenMouseUp," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7473 Screen->Cursor = TCursor(-2);
7477 Screen->Cursor = TCursor(-11);
7482 if(EndHLoc >= StartHLoc)
7486 if(EndVLoc >= StartVLoc)
7490 if(StartHLoc >= EndHLoc)
7500 if(StartVLoc >= EndVLoc)
7526 Screen->Cursor = TCursor(-2);
7592 if(IATVecPair.second != IATVecPair.first)
7610 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
7618 bool SelectVectorNamedElement =
false;
7619 AnsiString SelectTextString;
7624 SelectVectorNamedElement =
true;
7628 if(SelectVectorNamedElement)
7630 SelectTextString =
"##**" + TextPtr->TextString;
7634 SelectTextString = TextPtr->TextString;
7636 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
7645 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
7648 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) &&
7649 (UserGraphicPtr->VPos >= LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
7662 Screen->Cursor = TCursor(-2);
7668 Screen->Cursor = TCursor(-11);
7674 if(EndHLoc >= StartHLoc)
7678 if(EndVLoc >= StartVLoc)
7682 if(StartHLoc >= EndHLoc)
7692 if(StartVLoc >= EndVLoc)
7717 Screen->Cursor = TCursor(-2);
7746 Screen->Cursor = TCursor(-2);
7772 catch(
const Exception &e)
7805 throw Exception(
"Warning - Utilities->CallLog contains more than 50 items");
7832 catch(
const Exception &e)
7917 if(
WholeRailwayMoving && (GetAsyncKeyState(VK_LBUTTON) >= 0) && (GetAsyncKeyState(VK_RBUTTON) >= 0))
7920 Screen->Cursor = TCursor(-2);
7947 bool TrainPresent =
false;
7963 TDateTime TempExcessLCDownTime;
7972 if(TempExcessLCDownTime > TDateTime(0))
8001 bool ElementRemovedFlag =
false;
8018 int RouteNumber1, RouteNumber2, TrainID;
8025 ElementRemovedFlag =
true;
8041 bool WH1 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog1->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog1->Width +
OutputLog1->Left))
8044 bool WH2 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog2->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog2->Width +
OutputLog2->Left))
8047 bool WH3 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog3->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog3->Width +
OutputLog3->Left))
8050 bool WH4 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog4->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog4->Width +
OutputLog4->Left))
8053 bool WH5 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog5->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog5->Width +
OutputLog5->Left))
8056 bool WH6 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog6->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog6->Width +
OutputLog6->Left))
8059 bool WH7 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog7->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog7->Width +
OutputLog7->Left))
8062 bool WH8 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog8->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog8->Width +
OutputLog8->Left))
8065 bool WH9 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog9->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog9->Width +
OutputLog9->Left))
8068 bool WH10 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog10->Left) &&
8072 if(WH1 || WH2 || WH3 || WH4 || WH5 || WH6 || WH7 || WH8 || WH9 || WH10)
8093 AnsiString Type[15] =
8094 {
"Simple",
"Crossover",
"Points",
"Buffers",
"Bridge",
"SignalPost",
"Continuation",
"Platform",
"GapJump",
"FootCrossing",
"Unused",
"Concourse",
8095 "Parapet",
"NamedNonStationLocation",
"Erase"};
8097 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
8098 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
8100 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
8105 DevelopmentPanel->Caption = MouseStr +
"; TVPos: " + AnsiString(Position) +
"; H: " + AnsiString(HLoc) +
"; V: " + AnsiString(VLoc) +
8106 "; SpTg: " + AnsiString(TrackElement.
SpeedTag) +
"; Type: " + Type[TrackElement.
TrackType] +
"; Att: " + AnsiString(TrackElement.
Attribute)
8124 if((GetKeyState(VK_LBUTTON) >= 0) && (GetKeyState(VK_RBUTTON) >= 0) && (
TTCurrentEntryPtr > 0))
8255 Screen->Cursor = TCursor(-11);
8411 int RouteStartVecPos;
8421 if(FoundFlag && (RouteStartVecPos > -1))
8437 catch(
const Exception &e)
8455 InfoPanel->Caption =
"CALLING ON: Select signal for call on";
8469 catch(
const Exception &e)
8483 Screen->Cursor = TCursor(-11);
8525 Screen->Cursor = TCursor(-2);
8528 catch(
const Exception &e)
8542 Screen->Cursor = TCursor(-11);
8584 Screen->Cursor = TCursor(-2);
8587 catch(
const Exception &e)
8601 Screen->Cursor = TCursor(-11);
8644 Screen->Cursor = TCursor(-2);
8647 catch(
const Exception &e)
8661 Screen->Cursor = TCursor(-11);
8703 Screen->Cursor = TCursor(-2);
8706 catch(
const Exception &e)
8720 Screen->Cursor = TCursor(-11);
8757 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
8764 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
8773 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
8800 if((LeftExcess > 0) && (RightExcess > 0))
8802 else if((LeftExcess > 0) && (RightExcess <= 0))
8805 else if((LeftExcess <= 0) && (RightExcess > 0))
8813 if((TopExcess > 0) && (BotExcess > 0))
8815 else if((TopExcess > 0) && (BotExcess <= 0))
8818 else if((TopExcess <= 0) && (BotExcess > 0))
8828 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomIn");
8830 Screen->Cursor = TCursor(-2);
8834 catch(
const Exception &e)
8848 Screen->Cursor = TCursor(-11);
8871 Screen->Cursor = TCursor(-2);
8875 catch(
const Exception &e)
8903 catch(
const Exception &e)
8919 catch(
const Exception &e)
8940 ShowMessage(
"Please be aware when pasting that anything inside the pasted area will be overwritten.\n\nThis warning will not be shown again.");
8951 catch(
const Exception &e)
8974 TRect NewSelectRect(TLHCH, TLHCV, BRHCH, BRHCV);
9007 catch(
const Exception &e)
9026 catch(
const Exception &e)
9045 catch(
const Exception &e)
9093 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
9101 catch(
const Exception &e)
9149 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
9151 if(LeftPosAfterMirror < (
SelectRect.left * 16))
9161 catch(
const Exception &e)
9214 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
9226 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
9228 if(LeftPosAfterMirror < (
SelectRect.left * 16))
9240 catch(
const Exception &e)
9253 Screen->Cursor = TCursor(-11);
9270 int button = Application->MessageBox
9271 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9272 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9273 if(button == IDCANCEL)
9281 Screen->Cursor = TCursor(-2);
9318 if(IATVecPair.second != IATVecPair.first)
9336 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9343 bool SelectVectorNamedElement =
false;
9344 AnsiString SelectTextString;
9349 SelectVectorNamedElement =
true;
9353 if(SelectVectorNamedElement)
9355 SelectTextString =
"##**" + TextPtr->TextString;
9359 SelectTextString = TextPtr->TextString;
9361 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9370 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
9373 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
9374 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
9413 int MidHPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidVPosBeforeRotate;
9420 Screen->Cursor = TCursor(-2);
9425 catch(
const Exception &e)
9439 Screen->Cursor = TCursor(-11);
9456 int button = Application->MessageBox
9457 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9458 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9459 if(button == IDCANCEL)
9467 Screen->Cursor = TCursor(-2);
9504 if(IATVecPair.second != IATVecPair.first)
9522 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9529 bool SelectVectorNamedElement =
false;
9530 AnsiString SelectTextString;
9535 SelectVectorNamedElement =
true;
9539 if(SelectVectorNamedElement)
9541 SelectTextString =
"##**" + TextPtr->TextString;
9545 SelectTextString = TextPtr->TextString;
9547 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9556 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
9559 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
9560 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
9600 int MidVPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidHPosBeforeRotate;
9606 Screen->Cursor = TCursor(-2);
9611 catch(
const Exception &e)
9631 catch(
const Exception &e)
9650 catch(
const Exception &e)
9668 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values or leave blank for no change";
9671 ShowMessage(
"Note: length value will apply to each element's track within the selection.\n\nThis message will not be shown again.");
9681 catch(
const Exception &e)
9699 bool FoundFlag =
false;
9743 catch(
const Exception &e)
9773 catch(
const Exception &e)
9805 bool CheckLocationsExistInRailwayTrue =
true;
9809 Screen->Cursor = TCursor(-11);
9810 std::ifstream TTBLFile(AnsiString(
TimetableDialog->FileName).c_str(), std::ios_base::binary);
9811 if(TTBLFile.is_open())
9813 bool SessionFileFalse =
false;
9821 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
9823 Screen->Cursor = TCursor(-2);
9826 ShowMessage(
"Timetable preliminary integrity check failed - unable to load");
9831 catch(
const Exception &e)
9856 AnsiString LocName =
"";
9861 if((LocName ==
"") && (Train.
MidElement > -1))
9881 if((NextElementPosition > -1) && (NextEntryPos > -1))
9896 if((LocName ==
"") && (Train.
MidElement > -1))
9903 catch(
const Exception &e)
9927 AnsiString LocName =
"";
9932 if((LocName ==
"") && (Train.
MidElement > -1))
9940 if((LocName ==
"") && (Train.
MidElement > -1))
9971 int NextElementPos = -1;
9972 int NextEntryPos = -1;
9988 if((NextElementPos > -1) && (NextEntryPos > -1))
10022 catch(
const Exception &e)
10040 AnsiString LocName =
"";
10045 if((LocName ==
"") && (Train.
MidElement > -1))
10053 if((LocName ==
"") && (Train.
MidElement > -1))
10060 catch(
const Exception &e)
10089 int NextElementPos = -1;
10090 int NextEntryPos = -1;
10096 if((NextElementPos > -1) && (NextEntryPos > -1))
10116 catch(
const Exception &e)
10129 TTrain *TrainToBeJoinedBy;
10142 ShowMessage(
"Can't join two trains when both are without power");
10146 AnsiString TrainToBeJoinedByHeadCode = TrainToBeJoinedBy->
HeadCode;
10148 double OtherBrakeForce = TrainToBeJoinedBy->
MaxBrakeRate * TrainToBeJoinedBy->
Mass;
10150 double CombinedBrakeRate = (OtherBrakeForce + OwnBrakeForce) / (TrainToBeJoinedBy->
Mass + ThisTrain.
Mass);
10151 ThisTrain.
Mass += TrainToBeJoinedBy->
Mass;
10158 AnsiString LocName =
"";
10163 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
10167 if((LocName ==
"") && ThisTrain.
LeadElement > -1)
10171 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
10205 catch(
const Exception &e)
10235 AnsiString LocName =
"";
10240 if((LocName ==
"") && (Train.
MidElement > -1))
10248 if((LocName ==
"") && (Train.
MidElement > -1))
10264 catch(
const Exception &e)
10295 catch(
const Exception &e)
10311 if(NextElementPos < 0)
10313 throw Exception(
"Error, no element in front in PassRedSignalMenuItemClick");
10324 throw Exception(
"Error, next element not a signal type in PassRedSignalMenuItemClick");
10338 catch(
const Exception &e)
10364 int NextElementPos = -1;
10366 int NextEntryPos = -1;
10372 if((NextElementPos > -1) && (NextEntryPos > -1))
10381 catch(
const Exception &e)
10400 UnicodeString Message = UnicodeString(Train.
HeadCode) +
" will be removed from the railway - proceed?";
10401 int button = Application->MessageBox(Message.c_str(), L
"Please confirm", MB_YESNO);
10414 AnsiString LocName =
"";
10419 if((LocName ==
"") && (Train.
MidElement > -1))
10427 if((LocName ==
"") && (Train.
MidElement > -1))
10474 int FirstRouteElementVecPos = LeadTrackElement.
Conn[Train.
LeadExitPos];
10560 catch(
const Exception &e)
10575 Application->Terminate();
10589 catch(
const Exception &e)
10603 UnicodeString MessageStr =
10604 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
10605 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
10615 UnicodeString MessStr =
"";
10618 MessStr = UnicodeString(
"The railway and the timetable have both changed, exit without saving either?");
10622 MessStr = UnicodeString(
"The railway has changed, exit without saving?");
10626 MessStr = UnicodeString(
"The timetable has changed, exit without saving?");
10628 int button = Application->MessageBox(MessStr.c_str(), L
"Please confirm", MB_YESNO);
10641 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
10644 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
10663 catch(
const Exception &e)
10677 if((Shift.Contains(ssAlt)) && (Shift.Contains(ssCtrl)))
10690 else if(Key ==
'3')
10702 else if(Key ==
'4')
10706 else if(Key ==
'5')
10708 TMsgDlgButtons Buttons;
10709 Buttons << mbYes << mbNo;
10710 if(MessageDlg(
"Do you wish to allow facing signals next to bridges? If so please be aware that routes cannot be truncated to these signals.", mtWarning, Buttons, 0) == mrYes)
10720 else if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10724 else if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
10737 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
10754 else if(Key == VK_DOWN)
10759 else if(Key == VK_LEFT)
10764 else if(Key == VK_RIGHT)
10769 else if(Key == VK_HOME)
10775 else if(Key == VK_END)
10780 else if(Key == VK_END)
10794 if(Shift.Contains(ssShift) && !Shift.Contains(ssAlt) && !Shift.Contains(ssCtrl) &&
NewHomeButton->Enabled &&
NewHomeButton->Visible)
10805 if(!Shift.Contains(ssCtrl))
10868 if(Key ==
'S' || Key ==
's')
10879 if(Shift.Contains(ssShift))
10895 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
10942 if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10947 if(Key ==
'S' || Key ==
's')
10953 if(!Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10965 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10972 if(!Shift.Contains(ssShift) && Shift.Contains(ssCtrl))
10977 if(Key ==
'S' || Key ==
's')
10983 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
11004 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
11011 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
11017 if(Key ==
'S' || Key ==
's')
11022 else if(Key ==
'H' || Key ==
'h')
11036 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
11106 if(
SaveTTButton->Enabled && (Key ==
'T' || Key ==
't'))
11131 if(
FloatingInfoMenu->Enabled && !Shift.Contains(ssAlt) && Shift.Contains(ssCtrl) && Shift.Contains(ssShift))
11133 if(Key ==
'I' || Key ==
'i')
11139 if(Key ==
'S' || Key ==
's')
11143 else if(Key ==
'T' || Key ==
't')
11153 catch(
const Exception &e)
11163 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
11283 catch(
const Exception &e)
11296 Application->HelpKeyword(u
"Introduction");
11298 catch(
const Exception &e)
11308 const UnicodeString Link =
"http://www.railwayoperationsimulator.com";
11309 ::ShellExecute(Handle, NULL, (Link).c_str(), NULL, NULL, SW_SHOWNORMAL);
11332 catch(
const Exception &e)
11358 catch(
const Exception &e)
11384 catch(
const Exception &e)
11440 bool ErrorFlag =
false, TooBigFlag =
false;
11461 if(!ErrorFlag && !TooBigFlag)
11471 int KPH = (MPH * 1.609344) + 0.5;
11478 int MPH = (KPH * 0.621371) + 0.5;
11489 catch(
const EConvertError &ec)
11493 catch(
const Exception &e)
11528 bool ErrorFlag =
false, TooBigFlag =
false;
11549 if(!ErrorFlag && !TooBigFlag)
11559 int KW = (HP * 0.745699872) + 0.5;
11566 int HP = (KW * 1.340482574) + 0.5;
11577 catch(
const EConvertError &ec)
11581 catch(
const Exception &e)
11594 bool ErrorFlag =
false, TooBigFlag =
false;
11615 if(!ErrorFlag && !TooBigFlag)
11625 int KPH = (MPH * 1.609344) + 0.5;
11632 int MPH = (KPH * 0.621371) + 0.5;
11643 catch(
const EConvertError &ec)
11647 catch(
const Exception &e)
11661 bool ErrorFlag =
false, TooLongFlag =
false;
11664 for(
int x = 1; x <=
MileEdit->Text.Length(); x++)
11676 for(
int x = 1; x <=
ChainEdit->Text.Length(); x++)
11688 for(
int x = 1; x <=
YardEdit->Text.Length(); x++)
11700 TooLongFlag =
true;
11703 if(!ErrorFlag && !TooLongFlag)
11705 int Miles = 0, Chains = 0, Yards = 0, Metres = 0;
11718 Metres = int((Miles * 1609.344) + (Chains * 20.1168) + (Yards * 0.9144) + 0.5);
11727 catch(
const EConvertError &ec)
11731 catch(
const Exception &e)
11762 catch(
const Exception &e)
11798 "Changes have been made to the timetable clock - you may wish to save a session before resuming operation.\n\nTo cancel all changes re-click the 'Adjust the timetable clock' button then click the reset button BEFORE resuming operation.";
11805 catch(
const Exception &e)
11823 catch(
const Exception &e)
11842 catch(
const Exception &e)
11861 catch(
const Exception &e)
11880 catch(
const Exception &e)
11899 catch(
const Exception &e)
11918 catch(
const Exception &e)
11937 catch(
const Exception &e)
11956 catch(
const Exception &e)
11974 catch(
const Exception &e)
11988 double TTClockIncrement = 1.0 / 24;
11994 catch(
const Exception &e)
12008 double TTClockIncrement = 1.0 / 144;
12014 catch(
const Exception &e)
12028 double TTClockIncrement = 1.0 / 1440;
12034 catch(
const Exception &e)
12075 catch(
const Exception &e)
12089 InfoPanel->Caption =
"PRE-START: Presetting automatic signal routes";
12100 Screen->Cursor = TCursor(-11);
12102 bool PointsChanged, AtLeastOneSet =
false;
12103 int LastIteratorValue = 0;
12110 AtLeastOneSet =
true;
12125 ShowMessage(
"No presettable automatic signal routes are available");
12127 Screen->Cursor = TCursor(-2);
12130 catch(
const Exception &e)
12144 int DispW = (
Interface->Width - 64 - 16) / 16;
12146 int DispH = (
Interface->Height - 192) / 16;
12178 catch(
const Exception &e)
12208 catch(
const Exception &e)
12234 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
12239 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
12242 ShowMessage(
"Failed to store right hand signal setting, program will default to left hand signals when next loaded");
12260 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
12265 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
12277 catch(
const Exception &e)
12296 bool TooBigFlag =
false, BadCharsFlag =
false;
12301 for(
int x = 1; x <=
MTBFEditBox->Text.Length(); x++)
12305 BadCharsFlag =
true;
12318 ShowMessage(
"Maximum value allowed is 10,000");
12327 ShowMessage(
"Value must be a whole number with no special characters");
12344 catch(
const Exception &e)
12362 "Values can only be entered or changed in Pre-Start mode\ni.e. after selecting 'Operate railway' but before clicking 'Run'");
12366 catch(
const Exception &e)
12398 catch(
const Exception &e)
12424 catch(
const Exception &e)
12440 catch(
const Exception &e)
12461 catch(
const Exception &e)
12478 catch(
const Exception &e)
12495 catch(
const Exception &e)
12511 ShowMessage(
"No boxes ticked!");
12515 Screen->Cursor = TCursor(-11);
12516 AnsiString TTTitle;
12530 ShowMessage(
"Analysis complete and file created");
12535 Screen->Cursor = TCursor(-2);
12538 catch(
const Exception &e)
12580 int WidthNum = int(
MainScreen->Width / 160) + 1;
12581 int HeightNum = int(
MainScreen->Height / 144) + 1;
12582 for(
int x = 0; x < WidthNum; x++)
12584 for(
int y = 0; y < HeightNum; y++)
12697 bool BreakFlag =
false;
12799 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomOut");
12825 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting element";
12841 UnicodeString MessageStr =
"The railway has changed, close it without saving?";
12842 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
12889 std::ifstream VecFile(FileName);
12891 if(VecFile.is_open())
12911 bool GraphicsFollow =
false;
12912 int NumberOfActiveElements;
12925 if(!(EveryPrefDir->CheckOnePrefDir(0, NumberOfActiveElements, VecFile)))
12956 TDateTime First, Second;
12957 bool Finished =
false;
12959 First = TDateTime::CurrentDateTime();
12960 double TimeVal1 = 86400000 * double(First);
12964 Second = TDateTime::CurrentDateTime();
12965 double TimeVal2 = 86400000 * double(Second);
12966 if((TimeVal2 - TimeVal1) > Msec)
13016 if((LinkNumber1 == 1) || (LinkNumber1 == 3) || (LinkNumber1 == 7) || (LinkNumber1 == 9))
13024 if((LinkNumber2 == 1) || (LinkNumber2 == 3) || (LinkNumber2 == 7) || (LinkNumber2 == 9))
13176 InfoPanel->Caption =
"Select an option from the File, Mode or Help menus";
13332 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select preferred direction start location (right click to erase)";
13394 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13408 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
13435 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
13436 " in the folder where the 'Railway.exe' program file resides");
13477 OAListBox->Items->Add(L
"locate train");
13481 OAListBox->Items->Add(L
"headcode for");
13485 OAListBox->Items->Add(L
"Left click and");
13486 OAListBox->Items->Add(L
"hold grey area");
13487 OAListBox->Items->Add(L
"to move panel");
13517 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
13540 OAListBox->Items->Add(L
"locate train");
13544 OAListBox->Items->Add(L
"headcode for");
13548 OAListBox->Items->Add(L
"Left click and");
13549 OAListBox->Items->Add(L
"hold grey area");
13550 OAListBox->Items->Add(L
"to move panel");
13564 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13573 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13610 InfoPanel->Caption =
"ADDING TRACK: Select element then left click to add it. Right click an element to remove it.";
13631 InfoPanel->Caption =
"ADDING GRAPHIC: Left click layout to add SELECTED graphic, right click to remove ANY graphic.";
13636 InfoPanel->Caption =
"SELECTING USER GRAPHIC: Select the graphic file then add as many as necessary to the layout.";
13640 int HLoc, VLoc, Count;
13642 if(div(Count, 2).rem == 1)
13644 ShowMessage(
"Can't connect, there are an odd number of gaps");
13659 ShowMessage(
"Error - Even number of gaps but all set after first call to HighLightOneGap");
13669 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting gap";
13676 InfoPanel->Caption =
"ADDING/EDITING TEXT: Left click to add, right click first letter to erase, or left click first letter to edit)";
13691 InfoPanel->Caption =
"MOVING TEXT OR GRAPHIC: If text left click first letter, if graphic left click anywhere, then drag";
13698 InfoPanel->Caption =
"NAMING LOCATIONS: Click on location element to add or change name";
13706 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select first location (only non-default elements marked)";
13717 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select next location";
13719 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
13731 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
13741 InfoPanel->Caption =
"COPYING: Left click in selection && drag";
13765 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false; ;
13766 int ErasedTrackVectorPosition;
13767 Screen->Cursor = TCursor(-11);
13769 InfoPanel->Caption =
"CUT PROCESSING: Please do not click the mouse";
13776 if(EraseSuccessfulFlag)
13778 if(ErasedTrackVectorPosition > -1)
13788 int HighSelectVPos =
SelectRect.bottom * 16;
13794 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13800 TextChangesMade =
true;
13810 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13811 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13814 GraphicChangesMade =
true;
13821 Screen->Cursor = TCursor(-2);
13826 InfoPanel->Caption =
"CUTTING: Left click in selection && drag";
13842 if(NeedToLink || TextChangesMade || GraphicChangesMade)
13857 bool NeedToLink =
false;
13858 bool TrackLinkingRequiredFlag;
13859 Screen->Cursor = TCursor(-11);
13861 InfoPanel->Caption =
"PASTING: Please wait";
13868 bool TrackEraseSuccessfulFlag;
13869 int ErasedTrackVectorPosition;
13871 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
13873 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
13876 if(ErasedTrackVectorPosition > -1)
13891 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13906 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13907 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13928 bool InternalChecks =
false;
13932 TrackLinkingRequiredFlag, InternalChecks);
13948 if(TrackLinkingRequiredFlag)
13956 TextPtr->HPos += HDiff * 16;
13957 TextPtr->VPos += VDiff * 16;
13958 AnsiString TempString = TextPtr->TextString;
13974 if(TextPtr->TextString.SubString(1, 4) ==
"##**")
13976 TempString = TextPtr->TextString.SubString(5, TextPtr->TextString.Length());
13979 TextPtr->TextString =
"";
13991 for(TTrack::TUserGraphicVector::iterator GraphicPtr =
Track->
SelectGraphicVector.begin(); GraphicPtr < Track->SelectGraphicVector.end();
13994 GraphicPtr->HPos += HDiff * 16;
13995 GraphicPtr->VPos += VDiff * 16;
14008 Screen->Cursor = TCursor(-2);
14022 UnicodeString MessageStr =
"Selected area will be deleted - proceed?";
14023 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
14028 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false;
14029 int ErasedTrackVectorPosition;
14030 Screen->Cursor = TCursor(-11);
14032 InfoPanel->Caption =
"DELETING: Please wait";
14039 if(EraseSuccessfulFlag)
14041 if(ErasedTrackVectorPosition > -1)
14051 int HighSelectVPos =
SelectRect.bottom * 16;
14057 AnsiString Check = TextPtr->TextString;
14058 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
14064 TextChangesMade =
true;
14083 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
14084 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
14089 if((UserGraphicPtr->HPos == GraphicPtr->HPos) && (UserGraphicPtr->VPos == GraphicPtr->VPos) &&
14090 (UserGraphicPtr->Width == GraphicPtr->Width) && (UserGraphicPtr->Height == GraphicPtr->Height) &&
14091 (UserGraphicPtr->FileName == GraphicPtr->FileName))
14094 GraphicChangesMade =
true;
14111 if(NeedToLink || TextChangesMade || GraphicChangesMade)
14115 Screen->Cursor = TCursor(-2);
14167 bool LeadingPointsAtLastElement =
false;
14170 if(LeadingPointsAtLastElement)
14172 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Can't end on leading points, select next location or truncate";
14177 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select next preferred direction location (right click to truncate)";
14182 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Add selection or select next location (right click to truncate)";
14197 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
14237 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
14280 Display->
PerformanceLog(15, TimeMessage +
"Timetable clock speed changed to one sixteenth normal");
14285 if(TTClockTimeChange > 0.000347)
14288 int MinsIncrease = ((TTClockTimeChange * 1440) + 0.5);
14289 int HoursIncrease = 0;
14290 while(MinsIncrease >= 60)
14293 MinsIncrease -= 60;
14295 if(HoursIncrease == 0)
14296 TimeMessage +=
"Timetable clock incremented by " + AnsiString(MinsIncrease) +
"m";
14297 else if(MinsIncrease == 0)
14298 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h";
14300 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h " + AnsiString(MinsIncrease) +
"m";
14311 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
14319 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
14328 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
14356 float LockDelay = 120.0;
14362 bool BreakFlag =
false;
14366 if((TTClockTime - LRVIT->LockStartTime) > TDateTime(LockDelay / 86400))
14369 AnsiString(LRVIT->LastTrackVectorPosition));
14370 while(Route.
LastElementPtr(9)->GetTrackVectorPosition() != LRVIT->TruncateTrackVectorPosition)
14383 if(Route.
LastElementPtr(17)->GetTrackVectorPosition() == LRVIT->TruncateTrackVectorPosition)
14422 int TempLockedVectorNumber;
14432 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->FirstDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 0))
14435 AutoSigVectorIT->AccessNumber++;
14438 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->SecondDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 1))
14441 AutoSigVectorIT->AccessNumber++;
14444 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->ThirdDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 2))
14447 AutoSigVectorIT->AccessNumber++;
14455 if(AutoSigVectorIT->AccessNumber > 2)
14469 TPoint MousePoint = Mouse->CursorPos;
14470 int ScreenX = MousePoint.x -
MainScreen->ClientOrigin.x;
14471 int ScreenY = MousePoint.y -
MainScreen->ClientOrigin.y;
14483 ((MousePoint.y - ClientOrigin.y) >=
PerformancePanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14495 ((MousePoint.y - ClientOrigin.y) >=
TimetableEditPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14504 AnsiString TrackFloat =
"", TrainStatusFloat =
"", TrainTTFloat =
"";
14505 bool ShowTrackFloatFlag =
false, ShowTrainStatusFloatFlag =
false, ShowTrainTTFloatFlag =
false;
14516 bool MouseOverOAPanel =
false;
14520 ((MousePoint.y - ClientOrigin.y) >=
OperatorActionPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14523 MouseOverOAPanel =
true;
14530 bool ActiveTrackFoundFlag =
false, InactiveTrackFoundFlag =
false, TwoTrack =
false;
14531 AnsiString Length01Str =
"", Length23Str =
"", SpeedLimit01Str =
"", SpeedLimit23Str =
"";
14532 AnsiString StationEntryStopLinkPos1Str =
"", StationEntryStopLinkPos2Str =
"";
14533 AnsiString ATrackSN =
"", ATrackTN =
"", IATrackSN =
"", LengthAndSpeedCaption =
"";
14534 AnsiString SigAspectString =
"";
14538 if(InactiveTrackFoundFlag)
14543 if(ActiveTrackFoundFlag)
14550 if((ATrackTN !=
"") && (!InactiveTrackFoundFlag || ((InactiveTrackElement.
TrackType !=
Platform) &&
14554 ShowMessage(
"Error - Track has timetable name without corresponding plat/named loc");
14559 ShowMessage(
"Error - plat/named loc and track have different names, or plat/named loc named but not track");
14565 Length01Str = AnsiString(ActiveTrackElement.
Length01);
14566 if(Length01Str ==
"-1")
14567 Length01Str =
"Not Set";
14568 SpeedLimit01Str = AnsiString(ActiveTrackElement.
SpeedLimit01);
14569 if(SpeedLimit01Str ==
"-1")
14570 SpeedLimit01Str =
"Not Set";
14573 Length23Str = AnsiString(ActiveTrackElement.
Length23);
14574 if(Length23Str ==
"-1")
14575 Length23Str =
"Not Set";
14576 SpeedLimit23Str = AnsiString(ActiveTrackElement.
SpeedLimit23);
14577 if(SpeedLimit23Str ==
"-1")
14578 SpeedLimit23Str =
"Not Set";
14581 LengthAndSpeedCaption =
"Straight track length = " + Length01Str +
" m" +
'\n' +
"Diverging track length = " + Length23Str +
" m" +
'\n' +
14582 "Straight track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Diverging track speed limit = " + SpeedLimit23Str +
" km/h";
14586 LengthAndSpeedCaption =
"Left diverging track length = " + Length01Str +
" m" +
'\n' +
"Right diverging track length = " + Length23Str +
14587 " m" +
'\n' +
"Left diverging track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Right diverging track Speed Limit = " +
14588 SpeedLimit23Str +
" km/h";
14593 if((ActiveTrackElement.
SpeedTag == 15) || (ActiveTrackElement.
SpeedTag == 46))
14595 LengthAndSpeedCaption =
"Horizontal track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
14596 "Horizontal track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
14598 else if(ActiveTrackElement.
SpeedTag == 47)
14600 LengthAndSpeedCaption =
"Horizontal track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
14601 "Horizontal track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
14603 else if(ActiveTrackElement.
SpeedTag == 45)
14605 LengthAndSpeedCaption =
"Vertical track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
14606 "Vertical track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
14608 else if(ActiveTrackElement.
SpeedTag == 44)
14610 LengthAndSpeedCaption =
"Vertical track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
14611 "Vertical track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
14613 else if(ActiveTrackElement.
SpeedTag == 16)
14615 LengthAndSpeedCaption =
"Top left to bottom right track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
14616 " m" +
'\n' +
"Top left to bottom right track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " +
14617 SpeedLimit23Str +
" km/h";
14622 LengthAndSpeedCaption =
"Top track length = " + Length01Str +
" m" +
'\n' +
"Bottom track length = " + Length23Str +
" m" +
'\n' +
14623 "Top track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Bottom track speed limit = " + SpeedLimit23Str +
" km/h";
14628 LengthAndSpeedCaption =
"Track length = " + Length01Str +
" m" +
'\n' +
"Track speed limit = " + SpeedLimit01Str +
" km/h";
14631 if(ActiveTrackFoundFlag)
14635 ShowTrackFloatFlag =
true;
14638 TrackFloat =
"Location = " + ATrackTN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14640 else if(ATrackSN !=
"")
14642 TrackFloat =
"Location = " + ATrackSN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14645 else if(InactiveTrackFoundFlag)
14647 TrackFloat =
"Location unnamed\n" + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14652 TrackFloat = LengthAndSpeedCaption +
'\n' +
"Track Element ID = " + AnsiString(ActiveTrackElement.
ElementID);
14658 SigAspectString =
"\nThree-aspect signal";
14662 SigAspectString =
"\nTwo-aspect signal";
14666 SigAspectString =
"\nGround signal";
14670 SigAspectString =
"\nFour-aspect signal";
14672 TrackFloat += SigAspectString;
14675 else if(InactiveTrackFoundFlag)
14678 ShowTrackFloatFlag =
true;
14681 if(IATrackSN ==
"")
14683 TrackFloat =
"Location unnamed\nID = " + AnsiString(InactiveTrackElement.
ElementID);
14687 TrackFloat =
"Location = " + IATrackSN +
'\n' +
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
14692 TrackFloat =
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
14698 bool OAListBoxFloatRequired =
false;
14703 AnsiString FormatOneDPStr =
"####0.0";
14704 AnsiString FormatNoDPStr =
"#######0";
14706 AnsiString MaxBrakeStr =
"";
14707 AnsiString SpecialStr =
"";
14712 int X =
OAListBox->ScreenToClient(MousePoint).x;
14713 int Y =
OAListBox->ScreenToClient(MousePoint).y;
14714 int TrainID = -1, ContinuationPos = -1;
14717 OAListBoxFloatRequired =
true;
14720 ShowTrainStatusFloatFlag =
true;
14724 ShowTrainTTFloatFlag =
true;
14726 if((TrainID > -1) && (ShowTrainStatusFloatFlag || ShowTrainTTFloatFlag))
14732 else if(ContinuationPos > -1)
14741 if(!OAListBoxFloatRequired)
14744 if(FoundFlag && !MouseOverOAPanel)
14752 ShowTrainStatusFloatFlag =
true;
14757 ShowTrainTTFloatFlag =
true;
14767 TrainStatusFloat =
"No trains expected";
14768 TrainTTFloat =
"No timetable";
14770 ShowTrainStatusFloatFlag =
true;
14772 ShowTrainTTFloatFlag =
true;
14783 AnsiString Caption;
14785 if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14791 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14793 Caption = TrackFloat;
14795 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14797 Caption = TrainStatusFloat;
14799 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14801 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14803 else if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14805 if(TrainStatusFloat ==
"No trains expected")
14806 Caption = TrainStatusFloat;
14808 Caption = TrainTTFloat;
14810 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14812 if(TrainStatusFloat ==
"No trains expected")
14813 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14815 Caption = TrainTTFloat +
'\n' +
'\n' + TrackFloat;
14817 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14819 if(TrainStatusFloat ==
"No trains expected")
14820 Caption = TrainStatusFloat;
14822 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat;
14824 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14826 if(TrainStatusFloat ==
"No trains expected")
14827 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14829 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat +
'\n' +
'\n' + TrackFloat;
14832 int WindowOffsetLeft = 16;
14833 int WindowOffsetRight = 16;
14834 if(OAListBoxFloatRequired)
14836 WindowOffsetLeft = 32;
14837 WindowOffsetRight = 64;
14843 int Left = ScreenX +
MainScreen->Left + WindowOffsetRight;
14847 Left = ScreenX -
FloatingPanel->Width + 32 - WindowOffsetLeft;
14891 (CTEIt->second.TrainDataEntryPtr->TrainOperatingDataVector.at(CTEIt->second.RepeatNumber).RunningEntry !=
NotStarted)))
14898 AnsiString ServiceReferenceInfo =
"";
14902 if(CTEIt->second.RepeatNumber == 0)
14905 ServiceReferenceInfo =
"\nFirst service of ref. " + TTDEPtr->
ServiceReference;
14907 ServiceReferenceInfo =
"\nFirst service";
14910 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber);
14912 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber) +
" of ref. " +
14918 ServiceReferenceInfo =
"\nService reference " + TTDEPtr->
ServiceReference;
14922 SpecialStr =
"\nTrain under signaller control";
14924 if(EntrySpeed > LineSpeedLimit)
14925 EntrySpeed = LineSpeedLimit;
14930 if(EntrySpeed > LineSpeedLimit)
14931 EntrySpeed = LineSpeedLimit;
14935 TDateTime TempTime = CTEIt->first;
14937 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
14938 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nDelayed, was due at " +
14943 TDateTime TempTime = CTEIt->first;
14945 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
14946 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nExpected at " +
14954 CTEIt->second.IncrementalMinutes, CTEIt->second.IncrementalDigits);
14967 AnsiString HeadCode =
"", ServiceReferenceInfo =
"", Status =
"", CurrSpeedStr =
"", BrakePCStr =
"", NextStopStr =
"", TimeLeftStr =
"",
14968 TimeToNextMovementStr =
"", MassStr =
"", PowerStr =
"";
14969 AnsiString FormatOneDPStr =
"####0.0", MaxBrakeStr =
"", MaxSpeedStr =
"", TrainStatusFloat;
14973 MassStr = AnsiString::FormatFloat(FormatNoDPStr, ((
double)Train.
Mass) / 1000);
14974 PowerStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
PowerAtRail / 1000 / 0.8);
14976 MaxSpeedStr =
"30";
14978 MaxSpeedStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
MaxRunningSpeed);
14982 TDateTime TimeLeft;
14984 MaxBrakeStr = AnsiString::FormatFloat(FormatNoDPStr, (Train.
MaxBrakeRate * Train.
Mass / 9810));
14993 ServiceReferenceInfo =
"\nFirst service";
14996 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber);
14998 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber) +
" of ref. " +
15009 Status =
"Stopped on signaller's instruction";
15011 Status =
"Not in service";
15013 Status =
"Stopped at buffers";
15015 Status =
"Stopped at signal";
15017 Status =
"Stopped - forward track occupied";
15025 Status =
"Stopped without power - train failed";
15027 Status =
"Stopped without power";
15030 Status =
"Stopped - signal passed at danger";
15032 Status =
"Derailed";
15034 Status =
"Crashed";
15041 Status =
"Accelerating";
15048 if(BrakePCRate < 55)
15049 Status =
"Light braking";
15050 else if(BrakePCRate < 90)
15051 Status =
"Heavy braking";
15053 Status =
"Emergency braking";
15059 if(BrakePCRate < 55)
15060 Status =
"Light braking";
15061 else if(BrakePCRate < 90)
15062 Status =
"Heavy braking";
15064 Status =
"Emergency braking";
15070 Status =
"Accelerating";
15076 Status =
"Accelerating";
15078 ((Train.
ExitSpeedFull - Train.
ExitSpeedHalf) * (
double(ElapsedDeltaT - FirstHalfTimeDeltaT) / double(SecondHalfTimeDeltaT)));
15087 Status =
"Coasting - train failed";
15091 Status =
"Coasting - no power";
15097 Status =
"Constant speed";
15108 Status =
"Coasting - train failed";
15112 Status =
"Coasting - no power";
15118 Status =
"Constant speed";
15125 NextStopStr =
"At signaller's discretion";
15127 NextStopStr =
"None";
15133 SpecialStr =
"Train under signaller control" + AnsiString(
'\n');
15137 SpecialStr =
"Restricted speed - being called on" + AnsiString(
'\n');
15141 if(RemTimeHalf < 0)
15144 if(RemTimeFull < 0)
15146 if(RemTimeHalf > 0)
15147 TimeLeft = RemTimeHalf;
15149 TimeLeft = RemTimeFull;
15150 TimeToNextMovementStr =
"Time to next movement (sec) = " + TimeLeftStr.FormatFloat(FormatOneDPStr, TimeLeft);
15152 TimeToNextMovementStr =
"";
15156 MaxSpeedStr +
"km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr +
15157 Status +
'\n' +
"Next: " + NextStopStr;
15162 MaxSpeedStr +
"km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr +
15163 Status +
": " + CurrSpeedStr.FormatFloat(FormatNoDPStr, CurrSpeed) +
"km/h" +
'\n' +
"Next: " + NextStopStr;
15166 return TrainStatusFloat;
15249 InfoPanel->Caption =
"PRE-START: Route setting in progress";
15251 InfoPanel->Caption =
"OPERATING: Route setting in progress";
15373 bool Manual =
false;
15420 throw Exception(
"Failed to find a route at LC position HLoc = " + (AnsiString)H +
" VLoc = " + (AnsiString)V);
15425 if(RouteNumber > -1)
15459 bool SaveRailwayButtonsFlag =
true;
15468 SaveRailwayButtonsFlag =
false;
15485 SaveRailwayButtonsFlag =
false;
15493 SaveRailwayButtonsFlag =
false;
15546 bool ZoomFlag =
true, HomeFlag =
true, NewHomeFlag =
true, ScreenLeftFlag =
true, ScreenRightFlag =
true, ScreenUpFlag =
true, ScreenDownFlag =
true,
15547 TrackBuildPanelEnabledFlag =
true, PrefDirPanelEnabledFlag =
true, OperatingPanelEnabledFlag =
true, TimetablePanelEnabledFlag =
true;
15549 AnsiString TrackBuildPanelLabelCaptionStr =
"Build/modify";
15550 AnsiString PrefDirPanelLabelCaptionStr =
"Preferred direction selection";
15551 AnsiString OperatingPanelLabelCaptionStr =
"Operation";
15552 AnsiString TimetablePanelLabelCaptionStr =
"Timetable editor";
15557 ScreenLeftFlag =
false;
15559 ScreenRightFlag =
false;
15561 ScreenUpFlag =
false;
15563 ScreenDownFlag =
false;
15568 ScreenLeftFlag =
false;
15570 ScreenRightFlag =
false;
15572 ScreenUpFlag =
false;
15574 ScreenDownFlag =
false;
15580 NewHomeFlag =
false;
15581 ScreenLeftFlag =
false;
15582 ScreenRightFlag =
false;
15583 ScreenUpFlag =
false;
15584 ScreenDownFlag =
false;
15590 TrackBuildPanelEnabledFlag =
false;
15591 TrackBuildPanelLabelCaptionStr =
"Disabled";
15592 PrefDirPanelEnabledFlag =
false;
15593 PrefDirPanelLabelCaptionStr =
"Disabled";
15594 OperatingPanelEnabledFlag =
false;
15595 OperatingPanelLabelCaptionStr =
"Disabled";
15596 TimetablePanelEnabledFlag =
false;
15597 TimetablePanelLabelCaptionStr =
"Disabled";
15605 OperatingPanelEnabledFlag =
false;
15606 OperatingPanelLabelCaptionStr =
"Disabled";
15609 NewHomeFlag =
false;
15610 ScreenLeftFlag =
false;
15611 ScreenRightFlag =
false;
15612 ScreenUpFlag =
false;
15613 ScreenDownFlag =
false;
15627 NewHomeFlag =
false;
15628 ScreenLeftFlag =
false;
15629 ScreenRightFlag =
false;
15630 ScreenUpFlag =
false;
15631 ScreenDownFlag =
false;
15638 NewHomeFlag =
false;
15639 ScreenLeftFlag =
false;
15640 ScreenRightFlag =
false;
15641 ScreenUpFlag =
false;
15642 ScreenDownFlag =
false;
15650 NewHomeFlag =
false;
15651 ScreenLeftFlag =
false;
15652 ScreenRightFlag =
false;
15653 ScreenUpFlag =
false;
15654 ScreenDownFlag =
false;
15679 if(ScreenRightFlag)
15691 if(OperatingPanelEnabledFlag)
15695 if(TrackBuildPanelEnabledFlag)
15699 if(PrefDirPanelEnabledFlag)
15703 if(TimetablePanelEnabledFlag)
15722 bool CallOnValid =
false;
15728 CallOnValid =
true;
15821 Screen->Cursor = TCursor(-2);
15864 Caption =
"Railway: New railway under development";
15866 Caption =
"Railway: " +
RailwayTitle +
" under development";
15955 TFont *TempFont =
new TFont;
15957 TempFont->Style.Clear();
15958 TempFont->Name =
"MS Sans Serif";
15959 TempFont->Size = 10;
15961 TempFont->Charset = (TFontCharset)(0);
16067 if(NonPrefDirChangesMade)
16091 AnsiString CurrentDateTimeStr =
"", TimetableTimeStr =
"", SessionFileStr =
"";
16092 Screen->Cursor = TCursor(-11);
16093 CurrentDateTimeStr = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
16096 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
16099 SessionFileStr =
LoadSessionDialog->InitialDir +
"\\Session " + CurrentDateTimeStr +
"; Timetable time " + TimetableTimeStr +
"; " +
RailwayTitle +
16101 std::ofstream SessionFile(SessionFileStr.c_str());
16102 if(!(SessionFile.fail()))
16144 SessionFile.close();
16145 DeleteFile(SessionFileStr);
16146 Screen->Cursor = TCursor(-2);
16183 SessionFile.close();
16193 Screen->Cursor = TCursor(-2);
16196 catch(
const Exception &e)
16229 Screen->Cursor = TCursor(-11);
16234 if(!(SessionFile.fail()))
16241 int LastCharBeforeFloat = TempString.LastDelimiter(
'*');
16242 if((LastCharBeforeFloat == 0) || (LastCharBeforeFloat == TempString.Length()))
16249 AnsiString FloatStr = TempString.SubString(LastCharBeforeFloat + 1, TempString.Length() - LastCharBeforeFloat);
16265 bool GraphicsFollow =
false;
16281 SessionFile.close();
16282 Screen->Cursor = TCursor(-2);
16283 ShowMessage(
"Corruption in preferred direction section of the session file, session can't be loaded");
16291 SessionFile.close();
16292 Screen->Cursor = TCursor(-2);
16293 ShowMessage(
"Corruption in route section of the session file, session can't be loaded");
16305 if(TempString ==
"***BarriersDownVector***")
16313 SessionFile.close();
16314 Screen->Cursor = TCursor(-2);
16315 ShowMessage(
"Unable to load timetable section of the session file, session can't be loaded");
16322 SessionFile.close();
16323 Screen->Cursor = TCursor(-2);
16324 throw Exception(
"TimetableTitle null in LoadSession");
16342 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
16343 " in the folder where the 'Railway.exe' program file resides");
16349 SessionFile.get(TempChar);
16350 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
16352 SessionFile.get(TempChar);
16354 if(SessionFile.eof())
16358 SessionFile.close();
16370 double PowerDouble;
16380 SessionFile.get(TempChar);
16381 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
16383 SessionFile.get(TempChar);
16385 if(!SessionFile.eof())
16387 if((TempChar !=
'0') && (TempChar !=
'1'))
16389 throw Exception(
"TempChar value = " + AnsiString(TempChar) +
", should be 0 or 1");
16392 if(TempChar ==
'0')
16397 SessionFile.close();
16433 ShowMessage(
"Session file integrity check failed, unable to load session.");
16435 Screen->Cursor = TCursor(-2);
16439 catch(
const Exception &e)
16441 if((e.Message.Pos(
"esource") > 0) || (e.Message.Pos(
"arameter") > 0))
16443 Screen->Cursor = TCursor(-2);
16454 UnicodeString MessageStr =
16455 "Insufficient memory available to load the file, and partial load likely to be corrupt. Application will terminate. Try loading the session as the first action after reloading the program.";
16457 Application->MessageBox(MessageStr.c_str(), L
"Out of memory", MB_OK | MB_ICONERROR);
16458 Application->Terminate();
16529 if(OpMode ==
"PreStart")
16587 AnsiString OpMode =
"";
16594 else if((OpMode !=
"PreStart") && (OpMode !=
"NotPreStart"))
16826 SessionFile.close();
16827 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
16841 ShowMessage(
"Failed to open temporary timetable file. Unable to save the session");
16847 char *Buffer =
new char[10000];
16852 BytesRead = FileRead(Handle, Buffer, 10000);
16853 SessionFile.write(Buffer, BytesRead);
16854 if(BytesRead < 10000)
16860 SessionFile.close();
16861 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::out);
16885 if(!FileExists(TimetableFileName))
16892 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
16894 int Handle = FileOpen(TimetableFileName, fmOpenRead);
16901 Handle = FileOpen(TimetableFileName, fmOpenRead);
16911 char *Buffer =
new char[10000];
16916 BytesRead = FileRead(Handle, Buffer, 10000);
16917 ErrorFile.write(Buffer, BytesRead);
16918 if(BytesRead < 10000)
16925 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::out);
16953 int TempTTFileNumber = 0;
16955 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
16957 TempTTFileNumber++;
16965 if(!TTBFile.fail())
16967 char *Buffer =
new char[10000];
16968 char TempChar = (char)(SessionFile.peek());
16969 if(TempChar ==
'\n')
16970 SessionFile.get(TempChar);
16971 if(!SessionFile.getline(Buffer, 10000,
'\0'))
16980 for(
int x = 0; x < 10000; x++)
16982 if(Buffer[x] !=
'\0')
16987 while(AnsiString(Buffer) !=
"***End***")
16989 TTBFile.write(Buffer, Count);
16990 TTBFile.write(&Zero, 1);
16992 if(!SessionFile.getline(Buffer, 10000,
'\0'))
17001 for(
int x = 0; x < 10000; x++)
17003 if(Buffer[x] !=
'\0')
17013 bool GiveMessagesFalse =
false;
17014 bool CheckLocationsExistInRailwayTrue =
true;
17017 std::ifstream TTBLFile(
TempTTFileName.c_str(), std::ios_base::binary);
17018 if(TTBLFile.is_open())
17020 bool SessionFileTrue =
true;
17051 for(
int x = 0; x < NumberOfTrainEntries; x++)
17059 for(
int y = 0; y < NumberOfTrains; y++)
17084 AnsiString OutString;
17091 while(OutString !=
"***End***")
17100 if(SessionFile.fail())
17105 int NumberOfTrainEntries;
17112 for(
int x = 0; x < NumberOfTrainEntries; x++)
17114 int NumberOfTrains;
17120 for(
int y = 0; y < NumberOfTrains; y++)
17149 bool EndOfFile =
false;
17151 char *TrainTimetableString =
new char[10000];
17155 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
17156 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
17162 AnsiString OneLine(TrainTimetableString);
17163 bool FinalCallTrue =
true;
17165 CheckLocationsExistInRailway))
17167 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
17168 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
17171 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
17173 OneLine = AnsiString(TrainTimetableString);
17179 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
17180 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
17186 OneLine = AnsiString(TrainTimetableString);
17191 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
17193 if(EndOfFile && (Count < 2))
17196 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
17201 delete TrainTimetableString;
17208 ShowMessage(
"Timetable secondary integrity check failed - unable to load");
17244 bool EndOfFile =
false;
17246 char *TrainTimetableString =
new char[10000];
17250 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
17251 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
17257 AnsiString OneLine(TrainTimetableString);
17258 bool FinalCallTrue =
true;
17260 CheckLocationsExistInRailway))
17262 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
17263 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
17266 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
17268 OneLine = AnsiString(TrainTimetableString);
17274 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
17275 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
17281 OneLine = AnsiString(TrainTimetableString);
17286 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
17288 if(EndOfFile && (Count < 2))
17291 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
17296 delete TrainTimetableString;
17328 std::ifstream InFile(FileName.c_str());
17330 int NumberOfActiveElements;
17331 bool GraphicsFollow =
false;
17333 if(InFile.is_open())
17480 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
17486 if(TempString ==
"***BarriersDownVector***")
17524 ShowMessage(
"Session file failed to open - reason not known, unable to load session.");
17531 InFile.open(FileName.c_str());
17532 if(InFile.is_open())
17553 bool GraphicsFollow =
false;
17674 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
17680 if(TempString ==
"***BarriersDownVector***")
17759 InFile.get(TempChar);
17760 while(!InFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
17762 InFile.get(TempChar);
17793 double PowerDouble;
17823 AnsiString TempString =
"", Line1 =
"", Line2 =
"", Line3 =
"", Line4 =
"", Line5 =
"";
17824 char *Buffer =
new char[1000];
17827 InFile.get(TempChar);
17828 InFile.getline(Buffer, 1000);
17829 TempString = AnsiString(Buffer);
17830 while(TempString !=
"***End of performance file***")
17834 InFile.getline(Buffer, 1000);
17835 TempString = AnsiString(Buffer);
17846 AnsiString TempString =
"";
17849 InFile.get(TempChar);
17850 if(TempChar !=
'\n')
17860 while(TempString !=
"***End of performance file***")
17881 AnsiString OneLine = Text.SubString(1, Text.Pos(
'\x0D'));
17882 while((OneLine.Length() > 0) && OneLine[OneLine.Length()] <
' ')
17883 OneLine.SetLength(OneLine.Length() - 1);
17884 Text = Text.SubString(Text.Pos(
'\x0D'), Text.Length());
17885 while((Text.Length() > 0) && Text[1] <
' ')
17886 Text = Text.SubString(2, (Text.Length() - 1));
17887 OutFile << OneLine.c_str() <<
'\n';
17907 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
17909 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
17920 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
17922 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
17933 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
17935 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
17946 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17948 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17960 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17962 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17988 InfoPanel->Caption =
"Left click screen to zoom in at that position";
17993 InfoPanel->Caption =
"PAUSED: Railway state changes disabled";
18067 Screen->Cursor = TCursor(-11);
18068 AnsiString ErrorFileStr =
CurDir +
"\\errorlog.err";
18069 std::ofstream ErrorFile(ErrorFileStr.c_str());
18071 if(!(ErrorFile.fail()))
18074 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
18075 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
18076 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
18086 ErrorFile << Item.c_str() <<
'\n';
18093 ErrorFile << Item.c_str() <<
'\n';
18202 Screen->Cursor = TCursor(-2);
18219 int TempTTFileNumber = 0;
18221 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
18223 TempTTFileNumber++;
18226 int InHandle = FileOpen(InFileName, fmOpenRead);
18229 while(InHandle < 0)
18231 InHandle = FileOpen(InFileName, fmOpenRead);
18236 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
18244 while(OutHandle < 0)
18251 ShowMessage(
"Failed to save temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
18252 FileClose(InHandle);
18257 int CountIn, CountOut;
18258 char *Buffer =
new char[10000];
18262 CountIn = FileRead(InHandle, Buffer, 10000);
18263 CountOut = FileWrite(OutHandle, Buffer, CountIn);
18264 if(CountOut != CountIn)
18266 ShowMessage(
"Error in writing to the temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
18268 FileClose(InHandle);
18269 FileClose(OutHandle);
18273 if(CountIn < 10000)
18277 FileClose(InHandle);
18278 FileClose(OutHandle);
18323 int VarElements = 0;
18324 bool NamedLocPresent =
false;
18332 throw Exception(
"Error - failed to find track element at " + AnsiString(TE.
HLoc) +
" & " + AnsiString(TE.
VLoc) +
" in SetLengths");
18339 NamedLocPresent =
true;
18345 if(SpeedLimit != -1)
18350 if(SpeedLimit != -1)
18360 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) < 50))
18362 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
18365 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) > 200))
18367 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
18376 if((VarElements * 20) > Distance)
18378 ShowMessage(
"Required distance is less than the minimum, will set each element to the minimum (20m)");
18379 Distance = (VarElements * 20);
18381 if(VarElements == 0)
18384 ShowMessage(
"No elements selected");
18390 int RemainingDistance = Distance, RemainingVarElements = VarElements, NextLength = RemainingDistance / VarElements;
18398 if(NextLength < 20)
18422 RemainingDistance -= NextLength;
18423 RemainingVarElements--;
18424 if(RemainingVarElements > 0)
18425 NextLength = RemainingDistance / RemainingVarElements;
18450 ShowMessage(
"Nothing to save!");
18455 SaveRailwayDialog->Filter =
"Development file (*.dev)|*.dev|Railway file (*.rly)|*.rly";
18466 Screen->Cursor = TCursor(-11);
18468 AnsiString Extension =
"";
18476 if(!(VecFile.fail()))
18504 if((LastChar ==
'y') || (LastChar ==
'Y'))
18532 ShowMessage(
"File open failed prior to save");
18536 ShowMessage(
"Can't save: extension must be either '.dev', or '.rly' with railway ready for operation");
18538 Screen->Cursor = TCursor(-2);
18636 bool TextFound =
false;
18659 AnsiString(VPos) +
"," + AnsiString((
short)UseEnteredPosition));
18660 int VPosHi, VPosLo, TextPosHi, TextPosLo;
18663 if(!UseEnteredPosition)
18670 int Depth = abs(Font->Height);
18671 TextPosHi = VPosHi + 20;
18672 TextPosLo = VPosLo - Depth - 4;
18675 if(TextPosLo >= ScreenPosLo)
18677 else if(TextPosHi < ScreenPosHi)
18680 VPos = ScreenPosLo + 288;
18726 catch(
const Exception &e)
18803 AnsiString OpTimeToActDisplay;
18804 AnsiString OpTimeToActString;
18805 AnsiString HeadCode;
18806 float OpTimeToActFloat;
18818 HeadCode = HCandTrainPosParam.first;
18819 if(OpTimeToActFloat < 0.25)
18821 OpTimeToActString =
"NOW";
18823 else if(OpTimeToActFloat < 1)
18825 OpTimeToActString =
"<1";
18829 OpTimeToActString = AnsiString(floor(OpTimeToActFloat));
18831 if(OpTimeToActFloat < 60)
18833 OpTimeToActDisplay = HeadCode + AnsiString(
'\t') + OpTimeToActString;
18834 OAListBox->Items->Add(OpTimeToActDisplay);
18858 TPicture *PicPtr =
new TPicture;
18860 UGME.second = PicPtr;
18871 catch(
const EInvalidGraphic &e)
18874 "Incorrect file format, the file can't be loaded.\nEnsure that the file you want is a valid graphic file with extension .bmp, .gif, .jpg, or .png");
18876 catch(
const Exception &e)